package com.syyo.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.syyo.common.constant.ProductContant;
import com.syyo.common.enums.ResultEnum;
import com.syyo.common.exception.SysException;
import com.syyo.common.utils.MyListUtils;
import com.syyo.gulimall.product.domain.entity.AttrAttrgroupRelationEntity;
import com.syyo.gulimall.product.domain.entity.AttrEntity;
import com.syyo.gulimall.product.domain.entity.AttrGroupEntity;
import com.syyo.gulimall.product.domain.entity.CategoryEntity;
import com.syyo.gulimall.product.domain.req.AttrGroupReq;
import com.syyo.gulimall.product.domain.resp.AttrGroupWithAttrsResp;
import com.syyo.gulimall.product.domain.vo.SpuItemAttrGroupVo;
import com.syyo.gulimall.product.mapper.AttrAttrgroupRelationMapper;
import com.syyo.gulimall.product.mapper.AttrGroupMapper;
import com.syyo.gulimall.product.mapper.AttrMapper;
import com.syyo.gulimall.product.mapper.CategoryMapper;
import com.syyo.gulimall.product.service.AttrGroupService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 属性分组
 *
 * @author syyo
 * @email syyo@gmail.com
 * @date 2021-01-20 09:32:12
 */
@Service
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupMapper, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    private AttrGroupMapper attrGroupMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private AttrAttrgroupRelationMapper relationMapper;

    @Autowired
    private AttrMapper attrMapper;

    /**
     * 新增
     */
    @Override
    @Transactional
    public int add(AttrGroupReq req) {
        AttrGroupEntity attrGroup = new AttrGroupEntity();
        attrGroup.setAttrGroupName(req.getAttrGroupName());
        attrGroup.setDescript(req.getDescript());
        attrGroup.setIcon(req.getIcon());
        attrGroup.setSort(req.getSort());
        attrGroup.setCatelogId(req.getCatelogId());
        // 添加创建时间和更新时间
        int insert = attrGroupMapper.insert(attrGroup);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10001.getCode(), ResultEnum.E_10001.getMessage());
        }
        return insert;
    }

    /**
     * 删除
     */
    @Override
    @Transactional
    public int del(Integer id) {
        int insert = attrGroupMapper.deleteById(id);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10002.getCode(), ResultEnum.E_10002.getMessage());
        }
        return insert;
    }

    /**
     * 编辑
     */
    @Override
    @Transactional
    public int edit(AttrGroupReq req) {
        AttrGroupEntity attrGroup = new AttrGroupEntity();
        // 添加更新时间
        attrGroup.setAttrGroupId(req.getAttrGroupId());
        attrGroup.setAttrGroupName(req.getAttrGroupName());
        attrGroup.setDescript(req.getDescript());
        attrGroup.setIcon(req.getIcon());
        attrGroup.setSort(req.getSort());
        attrGroup.setCatelogId(req.getCatelogId());
        int insert = attrGroupMapper.updateById(attrGroup);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10003.getCode(), ResultEnum.E_10003.getMessage());
        }
        return insert;
    }

    /**
     * 详情
     */
    @Override
    public AttrGroupEntity findOne(Integer id) {
        AttrGroupEntity attrGroup = attrGroupMapper.selectById(id);
        Long catelogId = attrGroup.getCatelogId();
        List<Long> catelogIds = new ArrayList<>();
        catelogIds = findCategoryPids(catelogId, catelogIds);
        Collections.reverse(catelogIds);
        attrGroup.setCatelogIds(catelogIds.toArray(new Long[catelogIds.size()]));
        return attrGroup;
    }

    // 递归查询父级分类
    private List<Long> findCategoryPids(Long catelogId, List<Long> catelogIds) {
        catelogIds.add(catelogId);
        CategoryEntity categoryEntity = categoryMapper.selectById(catelogId);
        if (categoryEntity.getParentCid() != 0) {
            findCategoryPids(categoryEntity.getParentCid(), catelogIds);
        }
        return catelogIds;
    }


    /**
     * 列表
     */
    @Override
    public IPage<AttrGroupEntity> findPage(Integer pageNum, Integer pageSize, AttrGroupReq req) {
        Page<AttrGroupEntity> teacherPage = new Page<AttrGroupEntity>(pageNum, pageSize);
        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("catelog_id", req.getCatelogId());
        return attrGroupMapper.selectPage(teacherPage, wrapper);
    }

    /**
     * 列表
     */
    @Override
    public List<AttrGroupEntity> findAll(Long catelogId) {
        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("catelog_id", catelogId);
        return attrGroupMapper.selectList(wrapper);
    }

    /**
     * 列表
     */
    @Override
    public List<AttrEntity> findAllByGroupId(Long groupId) {
        List<AttrAttrgroupRelationEntity> list = relationMapper.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", groupId));
        List<Long> attrIds = list.stream().map((attr) -> {
            return attr.getAttrId();
        }).collect(Collectors.toList());
        List<AttrEntity> attrEntities = new ArrayList<>();
        if (MyListUtils.isNotEmpty(attrIds)) {
            attrEntities = attrMapper.selectBatchIds(attrIds);
        }
        return attrEntities;
    }

    @Override
    public int delRelevance(Integer attrId, Integer groupId) {
        int insert = relationMapper.delete(new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId).eq("attr_group_id", groupId));
        return insert;
    }

    @Override
    public IPage<AttrEntity> findAllNoRelevance(Long groupId, Integer pageNum, Integer pageSize) {
        // 1.查询当前分组只能关联自己所属分类的所有属性
        AttrGroupEntity attrGroupEntity = attrGroupMapper.selectById(groupId);

        Long catelogId = attrGroupEntity.getCatelogId();
        // 2.查询当前分组只能关联别的分组没有引用的属性
        // 2.1当前分类下的其他分组
        List<AttrGroupEntity> ohterGroups = attrGroupMapper.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
        List<Long> ohterGroupIds = ohterGroups.stream().map((item) -> {
            return item.getAttrGroupId();
        }).collect(Collectors.toList());

        // 2.2这些分组的属性
        List<AttrAttrgroupRelationEntity> groups = relationMapper.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", ohterGroupIds));
        List<Long> attrIds = groups.stream().map((item) -> {
            return item.getAttrId();
        }).collect(Collectors.toList());

        // 2.3从当前分类的所有属性移除这些属性,只查基本属性
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>().eq("catelog_id", catelogId).eq("attr_type", ProductContant.AttrEnum.ATTR_TYPE_BASE.getCode());
        if (MyListUtils.isNotEmpty(attrIds)) {
            wrapper.notIn("attr_id", attrIds);
        }
        Page<AttrEntity> teacherPage = new Page<AttrEntity>(pageNum, pageSize);
        return attrMapper.selectPage(teacherPage, wrapper);
    }

    @Override
    public List<AttrGroupWithAttrsResp> findAttrAndGroupByCatelogId(Long catelogId) {

        //1、查询分组信息
        List<AttrGroupEntity> attrGroupEntities = this.list(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));

        //2、查询所有属性
        List<AttrGroupWithAttrsResp> collect = attrGroupEntities.stream().map(group -> {
            AttrGroupWithAttrsResp attrGroupWithAttrsVo = new AttrGroupWithAttrsResp();
            BeanUtils.copyProperties(group, attrGroupWithAttrsVo);

            // 查询分类下的所有属性
            List<AttrAttrgroupRelationEntity> list = relationMapper.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", group.getAttrGroupId()));
            List<Long> attrIds = list.stream().map((attr) -> {
                return attr.getAttrId();
            }).collect(Collectors.toList());
            List<AttrEntity> attrEntities = new ArrayList<>();
            if (MyListUtils.isNotEmpty(attrIds)) {
                attrEntities = attrMapper.selectBatchIds(attrIds);
            }
            attrGroupWithAttrsVo.setAttrs(attrEntities);

            return attrGroupWithAttrsVo;
        }).collect(Collectors.toList());

        return collect;
    }

    @Override
    public List<SpuItemAttrGroupVo> getAttrGroupWithAttrsBySpuId(Long spuId, Long catalogId) {

        // 查询当前spu对应的所有属性的分组信息，和当前分组对应的属性值
        return attrGroupMapper.getAttrGroupWithAttrsBySpuId(spuId, catalogId);
    }
}